package Frontend

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

// 前端所需要的班级
type front_class struct {
	class_name   string
	persons_curr int
	money        float32
	tu_url       string
	choice       int
}

// 数据库中的专业字段
type mysql_profession struct {
	Id   int `db:"id"json:"id"`
	Name string `db:"name"json:"name"`
}

// 数据库中的课程字段
type mysql_course struct {
	Id            int  `db:"id"json:"id"`
	Name          string `db:"name"json:"name"`
	Profession_id int `db:"profession_id"json:"profession_id"`
}

// mysql里面的class数据库
type mysql_class struct {
	Id           int     `db:"id"json:"id"`
	Name         string  `db:"name"json:"class_name"`
	Course_id    int     `db:"course_id"json:"course_id"`
	Persons_max  int     `db:"persons_max"json:"persons_max"`
	Persons_curr int     `db:"persons_curr"json:"persons_curr"`
	Money        float32 `db:"money"json:"money"`
	Tu_url       string  `db:"tu_url"json:"tu_url"`
	Choice       string  `db:"choice"json:"choice"`
	Isok       	bool  `db:"isok"json:"isok"`  // 用户是否已经报名
}

var db *sqlx.DB

func InitDB() (err error) {
	dsn := "zhaosheng:ewPynjz8iF45YesH@tcp(127.0.0.1:3306)/zhaosheng?charset=utf8mb4&parseTime=True"
	//dsn := "zhaosheng:ewPynjz8iF45YesH@tcp(8.129.180.118:3306)/zhaosheng?charset=utf8mb4&parseTime=True"
	//dsn := "root:root@tcp(127.0.0.1:3306)/zhaosheng?charset=utf8mb4&parseTime=True"
	// 也可以使用MustConnect连接不成功就panic
	db, err = sqlx.Connect("mysql", dsn)
	if err != nil {
		fmt.Printf("connect DB failed, err:%v\n", err)
		return
	}
	fmt.Println("连接数据库完成")
	return
}

func Cloce_Db() {
	defer db.Close()
}

var professions []string // 给前台的专业数组
type front_class_data struct {
	Profession_name string        `json:"profession_name"`
	Course_name     string        `json:"course_name"`
	Class           []mysql_class `json:"class"`
}

// 获取数据库专业-课程-班级转为相应的数组数据。
func Fron_get_class(w http.ResponseWriter, r *http.Request) {
	professions = nil
	w.Header().Set("Access-Control-Allow-Origin", "*")
	data := r.URL.Query()
	// 获取课程数量
	sqlStr := "select COUNT(*) from course;"
	num_course := 0
	err := db.QueryRow(sqlStr).Scan(&num_course)
	if err != nil {
		fmt.Printf("scan failed, err:%v\n", err)
		return
	}
	fmt.Println("num_class=", num_course)
	var my_front_class_data = make([]front_class_data, num_course)
	// 读取数据库所有专业
	sqlStr = "select * from profession;"
	var my_profession []mysql_profession
	err = db.Select(&my_profession, sqlStr)
	if err != nil {
		fmt.Printf("query1 failed, err:%v\n", err)
		return
	}
	professions = append(professions, "全部")
	//fmt.Printf("my_class:%#v\n", my_profession)
	for i := 0; i < len(my_profession); i++ {
		professions = append(professions, my_profession[i].Name)
	}
	//fmt.Printf("professions:%s\n", professions)
	//fmt.Printf("my_front_class_data:", my_front_class_data)

	// 读取所有课程
	sqlStr = "select * from course;"
	var my_course []mysql_course
	err = db.Select(&my_course, sqlStr)
	if err != nil {
		fmt.Printf("query2 failed, err:%v\n", err)
		return
	}
	//fmt.Printf("my_course:", my_course)

	// 读取所有班级
	sqlStr = "select * from class;"
	var my_class []mysql_class
	err = db.Select(&my_class, sqlStr)
	if err != nil {
		fmt.Printf("query3 failed, err:%v\n", err)
		return
	}

	// 查询用户是否选择的这个课程
	user_id := data.Get("user_id")
	sqlStr = "select * from register_record where wx_user_id=?"
	var my_register_record []mysql_register_record
	err = db.Select(&my_register_record, sqlStr, user_id)
	if err != nil {
		fmt.Printf("get failed, err:%v\n", err)
		return
	}
	for i:=0;i<len(my_register_record);i++ {
		for x:=0;x<len(my_class);x++{
			if my_class[x].Id==my_register_record[i].Class_id {
				my_class[x].Isok=true
			}
		}
	}

	// fmt.Printf("my_class:", my_class)
	// 添加专业和课程
	for i := 0; i < num_course; i++ {
		my_front_class_data[i].Course_name = my_course[i].Name
		fmt.Println(i, "--Profession_id=", my_course[i].Profession_id)
		for x := 0; x < len(my_profession); x++ {
			if my_course[i].Profession_id == my_profession[x].Id {
				my_front_class_data[i].Profession_name = my_profession[x].Name
			}
		}
	}
	// fmt.Println("my_front_class_data=", my_front_class_data)

	// 添加班级
	for x := 0; x < len(my_class); x++ {
		for y := 0; y < len(my_course); y++ {
			if my_class[x].Course_id == my_course[y].Id {
				my_front_class_data[y].Class = append(my_front_class_data[y].Class, my_class[x])
			}
		}
	}
	//fmt.Println("my_front_class_data=", my_front_class_data)
	//data, err := json.Marshal(my_front_class_data)
	//if err != nil {
	//	fmt.Println("json marshal failed")
	//	return
	//}
	//fmt.Printf("json=", data)

	var choose_data struct {
		Professions_name []string           `json:"professions_name"`
		Front_class_data []front_class_data `json:"front_class_data"`
	}
	choose_data1 := choose_data
	choose_data1.Professions_name = professions
	choose_data1.Front_class_data = my_front_class_data
	data_str, err := json.Marshal(choose_data1)
	if err != nil {
		fmt.Println("json marshal failed")
		return
	}
	fmt.Println("data_str=", string(data_str))
	w.Write(data_str) //给客户端返回数据。
}

type mysql_wx_user struct {
	Id                  int    `db:"id"json:"id"`
	Userid              string `db:"userid"json:"userid"`
	Name                string `db:"name"json:"name"`
	Iphone              string `db:"iphone"json:"iphone"`
	Idcard              string `db:"idcard"json:"idcard"`
	Address             string `db:"address"json:"address"`
	Party               string `db:"party"json:"party"`
	Degree              string `db:"degree"json:"degree"`
	Urgent_name         string `db:"urgent_name"json:"urgent_name"`
	Urgent_relationship string `db:"urgent_relationship"json:"urgent_relationship"`
	Urgent_iphone       string `db:"urgent_iphone"json:"urgent_iphone"`
	Disease             string `db:"disease"json:"disease"`
	Sex                 string `db:"sex"json:"sex"`
	Age                 string `db:"age"json:"age"`
}

// 判断前端传入 get参数userid 返回是否存在用户信息。
func Fron_get_is_exist(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")
	data := r.URL.Query()
	code := data.Get("userid")
	fmt.Println("get appid=", code)
	// 查询数据库
	sqlStr := `select * from wx_user where userid=?;`
	var my_wx_user mysql_wx_user
	err := db.Get(&my_wx_user, sqlStr, code)
	if err != nil {
		fmt.Printf("get failed, err:%v\n", err)
		jsonk := `{"isok":"no","msg":"不存在用户"}`
		fmt.Println("返回前台数据为：", jsonk)
		w.Write([]byte(jsonk)) //给客户端返回数据。
		return
	}
	fmt.Printf("my_wx_user:", my_wx_user)
	//JSON序列化：结构体-->JSON格式的字符串
	json_str, err := json.Marshal(my_wx_user)
	if err != nil {
		fmt.Println("json marshal failed")
		return
	}
	fmt.Printf("json:%s\n", json_str)
	jsonk := `{"isok":"ok","msg":"存在用户","data":` + string(json_str) + `}`
	fmt.Println("返回前台数据为：", jsonk)
	w.Write([]byte(jsonk)) //给客户端返回数据。
}

// 提交注册信息
func Fron_set_register(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")
	my := mysql_wx_user{
		Userid:              r.PostFormValue("userid"),
		Name:                r.PostFormValue("name"),
		Iphone:              r.PostFormValue("iphone"),
		Idcard:              r.PostFormValue("idcard"),
		Address:             r.PostFormValue("address"),
		Party:               r.PostFormValue("party"),
		Degree:              r.PostFormValue("degree"),
		Urgent_name:         r.PostFormValue("urgent_name"),
		Urgent_relationship: r.PostFormValue("urgent_relationship"),
		Urgent_iphone:       r.PostFormValue("urgent_iphone"),
		Disease:             r.PostFormValue("disease"),
		Sex:                 r.PostFormValue("sex"),
		Age:                 r.PostFormValue("age"),
	}
	fmt.Println("注册用户信息为：", my)
	sqlStr := `INSERT INTO wx_user (userid,name,iphone,idcard,address,party,degree,urgent_name,urgent_relationship,urgent_iphone,disease,sex,age) 
							VALUES (:userid,:name,:iphone,:idcard,:address,:party,:degree,:urgent_name,:urgent_relationship,:urgent_iphone,:disease,:sex,:age);`
	sq, err := db.NamedExec(sqlStr, my)
	if err != nil {
		fmt.Println("json marshal failed:", err)
		jsonk := `{"isok":"no","msg":"失败"}`
		fmt.Println("返回前台数据为：", jsonk)
		w.Write([]byte(jsonk)) //给客户端返回数据。
		return
	}
	fmt.Println("插入完成:%#v", sq)

	// 获取id号码
	// 查询数据库
	sqlStr = `select * from wx_user where userid=?;`
	var my_wx_user mysql_wx_user
	err = db.Get(&my_wx_user, sqlStr, r.PostFormValue("userid"))
	if err != nil {
		return
	}
	fmt.Println("my_wx_user:", my_wx_user.Id)
	fmt.Println("my_wx_user_str:", strconv.Itoa(my_wx_user.Id))
	jsonk := `{"isok":"ok","msg":"插入成功","user_id":` + strconv.Itoa(my_wx_user.Id) + `}`
	fmt.Println("返回前台数据为：", jsonk)
	w.Write([]byte(jsonk)) //给客户端返回数据。
}

type mysql_register_record struct {
	Id         int
	Wx_user_id int
	Statu      string
	Class_id   int
	Date       time.Time
	Date_str   string
}

// 前端获取用户报名记录列表 0=所有，1审核中 2已通过 3未通过
// user_id
func Fron_get_class_list(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")
	// 更具传入的statu 判断要的那些审核
	user_id := r.PostFormValue("user_id")
	statu := r.PostFormValue("statu")
	var sqlStr string
	if statu == "0" {
		sqlStr = `select * from register_record where wx_user_id=? ORDER BY id DESC;`
	} else if statu == "1" {
		sqlStr = `select * from register_record where wx_user_id=? and statu="审核中" ORDER BY id DESC;`
	} else if statu == "2" {
		sqlStr = `select * from register_record where wx_user_id=? and statu="已通过" ORDER BY id DESC;`
	} else if statu == "3" {
		sqlStr = `select * from register_record where wx_user_id=? and statu="未通过" ORDER BY id DESC;`
	}
	var my_register_record []mysql_register_record
	err := db.Select(&my_register_record, sqlStr, user_id)
	if err != nil {
		fmt.Printf("query failed, err:%v\n", err)
		return
	}
	fmt.Printf("users:%#v\n", my_register_record)
	// 数据库为空
	if my_register_record == nil {
		return
	}
	// 读取用户信息
	sqlStr = `select * from wx_user where id=?;`
	var my_wx_user mysql_wx_user
	err = db.Get(&my_wx_user, sqlStr, user_id)
	if err != nil {
		return
	}
	fmt.Printf("my_wx_user:", my_wx_user)

	// 读取所有班级
	sqlStr = "select * from class;"
	var my_class []mysql_class
	err = db.Select(&my_class, sqlStr)
	if err != nil {
		fmt.Printf("query failed, err:%v\n", err)
		return
	}

	// 用户页面record.html所需资料
	type class_datas struct {
		Register_record_id int `db:"register_record_id"json:"register_record_id"`
		Calss_id   int       `db:"calss_id"json:"calss_id"`
		Class_name string    `db:"class_name"json:"class_name"`
		Statu      string    `db:"statu"json:"statu"`
		Name       string    `db:"name"json:"name"`
		Iphone     string    `db:"iphone"json:"iphone"`
		Idcard     string    `db:"idcard"json:"idcard"`
		Date       string `db:"date"json:"date"`
	}

	var my_record = make([]class_datas, len(my_register_record))

	for i := 0; i < len(my_record); i++ {
		my_record[i].Register_record_id=my_register_record[i].Id
		my_record[i].Calss_id = my_register_record[i].Class_id
		my_record[i].Statu = my_register_record[i].Statu
		//my_record[i].Date = my_register_record[i].Date[:10]
		my_record[i].Date = my_register_record[i].Date.Format("2006-01-02 15:04:05")
		// 获取用户信息
		my_record[i].Name = my_wx_user.Name
		my_record[i].Idcard = my_wx_user.Idcard
		my_record[i].Iphone = my_wx_user.Iphone
		// 获取课程名称
		for x := 0; x < len(my_class); x++ {
			if my_record[i].Calss_id == my_class[x].Id {
				my_record[i].Class_name = my_class[x].Name
			}
		}
	}
	fmt.Println("my_record:", my_record)
	data, err := json.Marshal(my_record)
	if err != nil {
		fmt.Println("json marshal failed")
		return
	}
	fmt.Printf("json==\n", data)
	w.Write(data) //给客户端返回数据。
}

// 根据用户id好，查找id
func Fron_get_user_id(w http.ResponseWriter, r *http.Request) {
	data := r.URL.Query()
	user_id := data.Get("id")
	// 读取用户信息
	sqlStr := `select * from wx_user where id=?;`
	var my_wx_user mysql_wx_user
	err := db.Get(&my_wx_user, sqlStr, user_id)
	if err != nil {
		fmt.Printf("get failed, err:%v\n", err)
		jsonk := `{"isok":"no","msg":"不存在用户"}`
		fmt.Println("返回前台数据为：", jsonk)
		w.Write([]byte(jsonk)) //给客户端返回数据。
		return
	}
	//fmt.Printf("my_wx_user:", my_wx_user)
	//JSON序列化：结构体-->JSON格式的字符串
	json_str, err := json.Marshal(my_wx_user)
	if err != nil {
		fmt.Println("json marshal failed")
		return
	}
	fmt.Printf("json:%s\n", json_str)
	w.Write(json_str) //给客户端返回数据。
}

// 给前端课程-专业-班级名字 传入班级id账号
func Fron_get_class_name(w http.ResponseWriter, r *http.Request) {
	data := r.URL.Query()
	calss_id := data.Get("calss_id")
	// 读取指定所有班级
	sqlStr := "select * from class where id=?;"
	var my_class mysql_class
	err := db.Get(&my_class, sqlStr, calss_id)
	if err != nil {
		fmt.Printf("query failed, err:%v\n", err)
		return
	}

	var course_name string
	var profession_name string
	var money float32
	class_name := my_class.Name
	money = my_class.Money
	// 获取课程名称
	var my_course mysql_course
	sqlStr = "select * from course where id=?;"
	err = db.Get(&my_course, sqlStr, my_class.Course_id)
	if err != nil {
		fmt.Printf("query failed, err:%v\n", err)
		return
	}
	course_name = my_course.Name

	// 获取专业名称
	sqlStr = "select name from profession where id=?;"
	err = db.Get(&profession_name, sqlStr, my_course.Profession_id)
	if err != nil {
		fmt.Printf("query failed, err:%v\n", err)
		return
	}

	fmt.Println("class_name=", class_name)
	fmt.Println("course_name=", course_name)
	fmt.Println("profession_name=", profession_name)
	fmt.Println("money=", money)

	type Test struct {
		Class_name      string `db:"class_name"json:"class_name"`
		Course_name     string `db:"course_name"json:"course_name"`
		Profession_name string `db:"profession_name"json:"profession_name"`
		Money           string `db:"money"json:"money"`
	}

	var test = Test{
		Class_name:      class_name,
		Course_name:     course_name,
		Profession_name: profession_name,
		Money:           strconv.FormatFloat(float64(money), 'f', 2, 64),
	}

	json_str, err := json.Marshal(test)
	if err != nil {
		fmt.Println("json marshal failed")
		return
	}
	fmt.Printf("json:%s\n", json_str)

	w.Write([]byte(json_str)) //给客户端返回数据。
}

func Fron_set_up_register(w http.ResponseWriter, r *http.Request) {
	id_str := r.PostFormValue("id")
	id_int, _ := strconv.Atoi(id_str)
	my := mysql_wx_user{
		Id:                  id_int,
		Name:                r.PostFormValue("name"),
		Iphone:              r.PostFormValue("iphone"),
		Idcard:              r.PostFormValue("idcard"),
		Address:             r.PostFormValue("address"),
		Party:               r.PostFormValue("party"),
		Degree:              r.PostFormValue("degree"),
		Urgent_name:         r.PostFormValue("urgent_name"),
		Urgent_relationship: r.PostFormValue("urgent_relationship"),
		Urgent_iphone:       r.PostFormValue("urgent_iphone"),
		Disease:             r.PostFormValue("disease"),
		Sex:                 r.PostFormValue("sex"),
		Age:                 r.PostFormValue("age"),
	}
	fmt.Println("my=", my)

	sqlStr := "update wx_user set name=?,iphone=?,idcard=?,address=?,party=?,degree=?,urgent_name=?,urgent_relationship=?,urgent_iphone=?,disease=?,sex=?,age=? where id = ?"
	ret, err := db.Exec(sqlStr, my.Name, my.Iphone, my.Idcard, my.Address, my.Party, my.Degree, my.Urgent_name, my.Urgent_relationship, my.Urgent_iphone, my.Disease, my.Sex, my.Age, my.Id)
	if err != nil {
		fmt.Printf("update failed, err:%v\n", err)
		return
	}
	n, err := ret.RowsAffected() // 操作影响的行数
	if err != nil {
		fmt.Printf("get RowsAffected failed, err:%v\n", err)
		return
	}
	fmt.Printf("update success, affected rows:%d\n", n)
	jsonk := `{"isok":"ok","msg":"修改完成"}`
	fmt.Println("返回前台数据为：", jsonk)
	w.Write([]byte(jsonk)) //给客户端返回数据。
}

// 提交报名信息
func Fron_get_register_record(w http.ResponseWriter, r *http.Request) {
	id_int, _ := strconv.Atoi(r.PostFormValue("wx_user_id"))
	fmt.Println("id_int=", id_int)
	type class_id_arr struct {
		Class_name string  `db:"class_name"json:"class_name"`
		Class_id   int     `db:"class_id"json:"class_id"`
		Date       string  `db:"date"json:"date"`
		Money      float32 `db:"money"json:"money"`
		Statu      string  `db:"statu"json:"statu"`
	}
	//JSON反序列化：JSON格式的字符串-->结构体
	// 获取用户报名班级的json
	str := r.PostFormValue("class_res_list")
	fmt.Println("str=", str)
	var my_class_id_arr []class_id_arr
	err := json.Unmarshal([]byte(str), &my_class_id_arr)
	if err != nil {
		fmt.Println("json unmarshal failed!")
		fmt.Println(err)
		return
	}
	fmt.Println("my_class_id_arr=")
	fmt.Println(my_class_id_arr[0])

	sqlStr := "insert into register_record(wx_user_id,class_id,statu,date) values (?,?,?,?)"

	for i := 0; i < len(my_class_id_arr); i++ {
		ret, err := db.Exec(sqlStr, id_int, my_class_id_arr[i].Class_id, my_class_id_arr[i].Statu, my_class_id_arr[i].Date)
		if err != nil {
			fmt.Printf("insert failed, err:%v\n", err)
			return
		}
		theID, err := ret.LastInsertId() // 新插入数据的id
		if err != nil {
			fmt.Printf("get lastinsert ID failed, err:%v\n", err)
			return
		}
		fmt.Printf("insert success, the id is %d.\n", theID)

		sqlStr = "update class set persons_curr=persons_curr+1 where id = ?"
		ret, err = db.Exec(sqlStr, my_class_id_arr[i].Class_id)
		if err != nil {
			fmt.Printf("update failed, err:%v\n", err)
			return
		}
		n, err := ret.RowsAffected() // 操作影响的行数
		if err != nil {
			fmt.Printf("get RowsAffected failed, err:%v\n", err)
			return
		}
		fmt.Println("line:",n)
	}

	//my_register_record:=mysql_register_record{
	//	Wx_user_id: id_int,
	//	Statu:      r.PostFormValue("statu"),
	//	Class_id:   class_id,
	//	Date:       r.PostFormValue("date"),
	//}

	//r.PostFormValue("userid")
}
